﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ufida.u9.ait.openapi.utils;
using UFIDA.U9.Base;
using UFIDA.U9.Base.Currency;
using UFIDA.U9.CBO.FA.FA_UseStateBE;
using UFIDA.U9.CBO.HR.Department;
using UFIDA.U9.CBO.HR.Operator;
using UFIDA.U9.FA.FA_AlterDocBE;
using UFIDA.U9.FA.FA_AlterDocTypeBE;
using UFIDA.U9.FA.FA_AssetCardBE;
using UFIDA.U9.FA.FA_Enum;
using UFIDA.U9.FA.FAAlterDocBP;
using UFIDA.U9.ISV.FA;
using UFIDA.U9.PM.Rcv;
using UFSoft.UBF.Business;

namespace ufida.u9.ait.openapi
{
    internal class FAAlterBase
    {
        /// <summary>
        /// 资产变更单删除
        /// </summary>
        /// <param name="doc">资产变更单</param>
        /// <returns>资产变更单</returns>
        public static FA_AlterDoc DeleteDoc(FA_AlterDoc doc)
        {
            if (doc == null) return null;

            U9Utils.ClearCache();
            doc = doc.Key.GetEntity();
            if (!(doc.Statues == AssetCardCommonStatues.FAOpen
                || doc.Statues == AssetCardCommonStatues.Approving))
                throw new Exception($"单号[{doc.DocNo}]状态不为开立或审核中,不能删除");

            DeleteImportFAAlterDocSV sv= new DeleteImportFAAlterDocSV();
            sv.ImportFAAlterDocQueryConditionDTOs = new List<ImportFAAlterDocQueryConditionDTO>()
            {
                new ImportFAAlterDocQueryConditionDTO()
                {
                    ID = doc.ID,
                }
            };
            sv.Do();

            return doc;
        }
        /// <summary>
        /// 资产变更单提交
        /// </summary>
        /// <param name="doc">资产变更单</param>
        /// <returns>资产变更单</returns>
        public static FA_AlterDoc CommitDoc(FA_AlterDoc doc)
        {
            U9Utils.ClearCache();
            doc = doc.Key.GetEntity();
            if (doc.Statues != AssetCardCommonStatues.FAOpen)
                throw new Exception($"单号[{doc.DocNo}]状态不为开立");
            
            PostBP bp=new PostBP();
            bp.DocList = new List<UFIDA.U9.FA.FA_CommonBP.DocActionParam>()
            {
                new UFIDA.U9.FA.FA_CommonBP.DocActionParam()
                {
                    DocKey=doc.Key,
                    DocSysVersion=doc.SysVersion,
                }
            };
            AssetCardCommonStatues assetCardCommonStatues = bp.Do();
            return doc;
        }
        /// <summary>
        /// 资产变更单审核
        /// </summary>
        /// <param name="doc">资产变更单</param>
        /// <returns>资产变更单</returns>
        public static FA_AlterDoc ApproveDoc(FA_AlterDoc doc)
        {
            U9Utils.ClearCache();
            doc = doc.Key.GetEntity();
            if (doc.Statues == AssetCardCommonStatues.Approved)
                throw new Exception($"单号[{doc.DocNo}]状态为审核");
            
            ApproveBP bp = new ApproveBP();
            bp.DocList = new List<UFIDA.U9.FA.FA_CommonBP.DocActionParam>()
            {
                new UFIDA.U9.FA.FA_CommonBP.DocActionParam()
                {
                    DocKey=doc.Key,
                    DocSysVersion=doc.SysVersion,
                }
            };
            AssetCardCommonStatues assetCardCommonStatues = bp.Do();
            return doc;
        }
        /// <summary>
        /// 资产变更单创建
        /// </summary>
        /// <param name="dto">DTO数据</param>
        /// <returns>资产变更单实体</returns>
        public static FA_AlterDoc CreateDoc(FAAlterAITDTOData dto)
        {
            FA_AlterDoc doc;
            using(ISession session = Session.Open())
            {
                //创建头
                doc = CreateHead(dto);
                //创建行
                CreateLines(dto, doc);

                session.Commit();
            }

            return doc;
        }

        private static void CreateLines(FAAlterAITDTOData dto, FA_AlterDoc doc)
        {
            if (dto.FA_AlterDocDetailsList == null || dto.FA_AlterDocDetailsList.Count == 0)
                throw new Exception("行信息 必填");

            int rowno = 0;
            foreach(var linedto in dto.FA_AlterDocDetailsList)
            {
                rowno += 10;
                FA_AlterDocDetail line = FA_AlterDocDetail.Create(doc);

                if (linedto.AssetCard == null) throw new Exception("行 资产卡片 必填");
                AssetCard card = EntityUtils.GetDocEntity<AssetCard>(linedto.AssetCard.Code);
                line.AssetCard = card;
                line.OwnerDept=card.OwnerDept;
                line.Owner=card.Owner;
                line.OldOwnerDept = card.OwnerDept;
                line.OldOwner=card.Owner;
                line.OldAuditDept= card.AuditDept;
                line.OldAssetCategory = card.AssetCategory;
                line.LineNum = rowno;
                line.AuditDept = card.AuditDept;
                line.AssetCategory=card.AssetCategory;
                //资产财务信息变更数据
                CreateFAAssetAccountAlterObj(linedto, line);
                //资产使用信息变更
                CreateFAAssetTagUseInforAlterObjsList(linedto, line);
                //资产实物标签信息变更
                CreateFAAssetTagAlterObjsList(linedto, line);
            }
            
        }

        private static void CreateFAAssetTagUseInforAlterObjsList(FAAlterDocDetailAITDTOData linedto, FA_AlterDocDetail line)
        {
            if (linedto.FA_AssetTagUseInforAlterObjsList == null || linedto.FA_AssetTagUseInforAlterObjsList.Count == 0)
                return;

            AssetCard card = line.AssetCard;
            AssetCardAccountInformation accinfo = card.AssetAccountInfor[0];

            foreach(var alterdto in linedto.FA_AssetTagUseInforAlterObjsList)
            {
                if (alterdto.AssetTag == null) throw new Exception("变更信息 AssetTag 必填");
                AssetTag tag = EntityUtils.GetEntityByCode<AssetTag>(alterdto.AssetTag.Code);
                if (tag.AssetTagUsageInformation == null || tag.AssetTagUsageInformation.Count == 0)
                    throw new Exception($"标签[{tag.Code}]不存在使用信息");
                AssetTagUsageInformation useinfo = tag.AssetTagUsageInformation[0];

                FA_AssetTagUseInforAlterObj alter = FA_AssetTagUseInforAlterObj.Create(line);
                //旧值
                alter.OldUsagePrincipal = useinfo.UsagePrincipal;
                alter.OldUsageOrg = useinfo.OwnerUsageRelation;
                alter.OldUsageDept = useinfo.UsageDept;
                alter.OldToDate= useinfo.ToDate;
                alter.OldPercent = 1;
                alter.OldFromDate = useinfo.FromDate;

                //新值
                //使用组织
                alter.UsageOrg=useinfo.OwnerUsageRelation;
                //使用部门
                if (alterdto.UsageDept != null)
                {
                    alter.UsageDept=EntityUtils.GetEntityByCode<Department>(alterdto.UsageDept.Code);
                }
                else
                {
                    alter.UsageDept = useinfo.UsageDept;
                }
                //使用人员
                if (alterdto.UsagePrincipal != null)
                {
                    alter.UsagePrincipal=EntityUtils.GetEntityByCode<Operators>(alterdto.UsagePrincipal.Code);
                }
                else
                {
                    alter.UsagePrincipal=useinfo.UsagePrincipal;
                }
                alter.FromDate = line.FA_AlterDoc.BusinessDate;
                alter.ToDate = useinfo.ToDate;
                alter.Percentage = 1;

                //其他
                alter.AssetAccountInfor = accinfo;
                alter.AssetTag = tag;
                alter.DPBook = accinfo.DpBook;
                alter.AssetTagUsageInfor = useinfo;

                //使用变更时,需要创建事务变更明细
                FA_AssetTagAlterObj alter1 = FA_AssetTagAlterObj.Create(line);
                alter1.AssetTag = tag;
                alter1.AssetTagCode = tag.Code;
                //旧值/新值
                alter1.OldAssetLocation = tag.AssetLocation;
                alter1.OldNation = tag.AssetLocation.Location.Country;
                alter1.OldProvince = tag.AssetLocation.Location.Province;
                alter1.AssetLocation=tag.AssetLocation;
                alter1.Nation = tag.AssetLocation.Location.Country;
                alter1.Province=tag.AssetLocation.Location.Province;

            }
        }

        private static void CreateFAAssetTagAlterObjsList(FAAlterDocDetailAITDTOData linedto, FA_AlterDocDetail line)
        {
            if(linedto.FA_AssetTagAlterObjsList==null||linedto.FA_AssetTagAlterObjsList.Count==0) return;
        }

        private static void CreateFAAssetAccountAlterObj(FAAlterDocDetailAITDTOData linedto, FA_AlterDocDetail line)
        {
            //如果不是财务信息变更,直接退出
            if (linedto.FA_AssetAccountAlterObj == null || linedto.FA_AssetAccountAlterObj.Count == 0)
                return;

            AssetCard card = line.AssetCard;
            AssetCardAccountInformation accinfo = card.AssetAccountInfor[0];

            foreach (var alterdto in linedto.FA_AssetAccountAlterObj)
            {
                FA_AssetAccountAlterObj alter = FA_AssetAccountAlterObj.Create(line);
                alter.DPBook = accinfo.DpBook;
                alter.Currency = accinfo.Currency;
                alter.AssetAccountInfor = accinfo;

                //旧值
                alter.OldUseState = accinfo.UseState;
                alter.OldUsedLifeYear=accinfo.UsedLifeYear;
                alter.OldTax=accinfo.Tax;
                alter.OldSalvageRatio=accinfo.SalvageRatio;
                alter.OldOriginalValue=accinfo.OriginalValue;
                alter.OldFee=accinfo.Fee;
                alter.OldEstimateSalvageValue=accinfo.EstimateSalvageValue;
                alter.OldCostWithoutTax=accinfo.CostWithoutTax;
                alter.OldAccumulateDepreciate = accinfo.AccumulateDepreciation;


                //新值
                //使用状况
                if (alterdto.UseState != null)
                {
                    alter.UseState = EntityUtils.GetEntityByCode<UseState>(alterdto.UseState);
                }
                else
                {
                    alter.UseState = accinfo.UseState;
                }
                //使用年限
                if (alterdto.UsedLifeYear > 0)
                {
                    alter.UsedLifeYear = alterdto.UsedLifeYear;
                }
                else
                {
                    alter.UsedLifeYear = accinfo.UsedLifeYear;
                }
                //税额
                if (alterdto.Tax > 0)
                {
                    alter.Tax = alterdto.Tax;
                }
                else
                {
                    alter.Tax = accinfo.Tax;
                }
                //残值率
                if (alterdto.SalvageRatio > 0)
                {
                    alter.SalvageRatio = alterdto.SalvageRatio;
                }
                else
                {
                    alter.SalvageRatio = accinfo.SalvageRatio;
                }
                //资产原值
                if(alterdto.OriginalValue > 0)
                {
                    alter.OriginalValue = alterdto.OriginalValue;
                }
                else
                {
                    alter.OriginalValue = accinfo.OriginalValue;
                }
                //费用
                if (alterdto.Fee > 0)
                {
                    alter.Fee = alterdto.Fee;
                }
                else
                {
                    alter.Fee = accinfo.Fee;
                }
                //预估残值
                if (alterdto.EstimateSalvageValue > 0)
                {
                    alter.EstimateSalvageValue= alterdto.EstimateSalvageValue;
                }
                else
                {
                    alter.EstimateSalvageValue= accinfo.EstimateSalvageValue;
                }
                //CostWithoutTax 未税成本
                if (alterdto.CostWithoutTax > 0)
                {
                    alter.CostWithoutTax= alterdto.CostWithoutTax;
                }
                else
                {
                    alter.CostWithoutTax= accinfo.CostWithoutTax;
                }

                //AccumulateDepreciate 累计折旧
                if (alterdto.AccumulateDepreciate > 0)
                {
                    alter.AccumulateDepreciate= alterdto.AccumulateDepreciate;
                }
                else
                {
                    alter.AccumulateDepreciate = accinfo.AccumulateDepreciation;
                }
            }


        }

        private static FA_AlterDoc CreateHead(FAAlterAITDTOData dto)
        {
            FA_AlterDoc doc = FA_AlterDoc.Create();
            if (dto.DocumentType == null) throw new Exception("单据类型 必填");
            doc.DocumentType = EntityUtils.GetEntityByCode<FA_AlterDocType>(dto.DocumentType.Code);
            if (string.IsNullOrEmpty(dto.BusinessDate)) throw new Exception("业务日期 必填");
            doc.BusinessDate=DateTime.Parse(dto.BusinessDate);
            doc.AssetOwnerRelation = EntityUtils.GetAssetOwnerRelation();

            //组织
            doc.Org=Context.LoginOrg;
            doc.OwnerOrg = doc.Org;

            //其它
            doc.WorkFlowID = Guid.Empty;
            doc.StateMachineID= Guid.Empty;
            doc.AlterReason= AlterReasonUDCEnum.GetFromValue(dto.AlterReason);

            //资产变更单折旧账簿
            FA_AlterDocDPBook book= FA_AlterDocDPBook.Create(doc);
            book.DPBook = EntityUtils.GetDpBook();
            book.Count = 1;
            book.AffectDepreciatePeriod=EntityUtils.getPostPeriod(doc.BusinessDate);
            book.AccountingPeriod = book.AffectDepreciatePeriod;

            //FA_AlterDocAlterStylesList 资产变更单变更方式
            foreach(var styledto in dto.FA_AlterDocAlterStylesList)
            {
                FA_AlterDocAlterStyle style = FA_AlterDocAlterStyle.Create(doc);
                style.AlterStyle = FA_AlterStyleEnum.GetFromValue(styledto.AlterStyle);
            }
            
            return doc;
        }
    }
}
